package com.weitu.workflow.definition.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.weitu.permission.user.entity.User;
import com.weitu.util.DateTimeUtil;
import com.weitu.workflow.definition.constant.FlowDefConstants;
import com.weitu.workflow.definition.dao.WorkflowDefDao;
import com.weitu.workflow.definition.entity.WorkFlowDefinition;
import com.weitu.workflow.definition.mapper.WorkflowDefMapper;
import com.weitu.workflow.definition.service.WorkflowDefService;
import com.weitu.workflow.definition.util.WorkFlowSession;
import com.weitu.workflow.flowBusiness.entity.FlowBusiness;
import com.weitu.workflow.flowBusiness.service.FlowBusinessService;
import com.weitu.workflow.flowManagement.service.FlowManagementService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.fireflow.engine.RuntimeContext;
import org.fireflow.engine.definition.WorkflowDefinition;
import org.fireflow.engine.definition.WorkflowDefinitionInfo;
import org.fireflow.engine.impl.WorkflowSession;
import org.fireflow.engine.persistence.IPersistenceService;
import org.fireflow.model.*;
import org.fireflow.model.EventListener;
import org.fireflow.model.io.Dom4JFPDLSerializer;
import org.fireflow.model.io.FPDLSerializerException;
import org.fireflow.model.net.*;
import org.fireflow.model.resource.Application;
import org.fireflow.model.resource.Form;
import org.fireflow.model.resource.Participant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import java.io.IOException;
import java.text.Normalizer;
import java.util.*;


/**
 * Created by Administrator on 2017/3/17.
 */
@Service
public class WorkflowDefServiceImpl implements WorkflowDefService {
    @Autowired
    private FlowBusinessService flowBusinessService;
    @Autowired
    private WorkflowDefMapper workflowDefMapper;
    @Autowired
    private WorkflowDefDao workflowDefDao;
    @Autowired
    private RuntimeContext runtimeContext;
    @Autowired
    private TransactionTemplate transactionTemplate;
    @Autowired
    private IPersistenceService persistenceService;
    private static Dom4JFPDLSerializer serializer=new Dom4JFPDLSerializer();//流程定义文件序列化
    /***
     * 查询工作流定义数量
     * @return
     */
    public int queryWorkflowDefCount(Map<String,Object> paramMap){
        return this.workflowDefMapper.queryWorkflowDefCount(paramMap);
    }

    /***
     * 查询工作流定义集合
     * @return
     */
    public List<WorkflowDefinitionInfo> queryWorkflowDefList(Map<String,Object> paramMap){
        return this.workflowDefMapper.queryWorkflowDefList(paramMap);
    }
    /***
     * 查询工作流定义集合（用于数据表格显示，返回自定义的工作流类型）
     * @return
     */
    public List<WorkFlowDefinition> queryWorkflowDefTableList(Map<String,Object> paramMap){
        return this.workflowDefMapper.queryWorkFlowDefTableList(paramMap);
    }
    /***
     * 生成流程定义
     * @processId 流程id
     * @return
     */
    public String generateWorkflowDef(String processId){
        WorkflowProcess wfp = this.getWorkflowProcessCopy(processId);

        return serializerWorkflowProcess(wfp);
    }

    /**
     * 查询流程定义副本
     * @param processId
     * @return
     */
    private WorkflowProcess getWorkflowProcessCopy(String processId) {
        /*WorkflowProcess wfp = getWorkflowProcessByProcessId(processId+ FlowDefConstants.FLOWCOPY_SUFFIX);
        if (wfp == null) {
            final WorkflowDefinition def = new WorkflowDefinition();
            wfp = getWorkflowProcessByProcessId(processId);
            // 编辑工作流
            if (wfp != null) {
                wfp.setName(wfp.getName() + FlowDefConstants.FLOWCOPY_SUFFIX);
            }
            // 新建工作流
            else {
                wfp = new WorkflowProcess(processId+ FlowDefConstants.FLOWCOPY_SUFFIX);
                wfp.setDisplayName(processId);
            }
            def.setWorkflowProcess(wfp);
            def.setState(true);
            transactionTemplate.execute(new TransactionCallbackWithoutResult() {

                protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                    runtimeContext.getPersistenceService().saveOrUpdateWorkflowDefinition(def);
                }
            });
        }*/
        //20170607修改为将副本存在session中
        WorkflowProcess wfp = getWorkflowProcessByProcessId(processId);
        final WorkflowDefinition def = new WorkflowDefinition();
        if (wfp == null) {
            wfp = new WorkflowProcess(processId);
            wfp.setDisplayName(processId);
        }
        def.setWorkflowProcess(wfp);
        def.setState(true);
        //将流程定义放入session中
        WorkFlowSession.setWorkflowDefinition(def);
        wfp.setName(processId);
        return wfp;
    }
    /**
     * 从session中获取流程定义
     * @param processId
     * @return
     */
    private WorkflowProcess getWorkflowProcessFromSession(String processId) {

        //将流程定义放入session中
        WorkflowDefinition def= WorkFlowSession.getWorkflowDefinition(processId);
        if (def!=null){
            return def.getWorkflowProcess();
        }
        return null;
    }

    /***
     * 根据流程id获取流程对象
     * @param processId
     * @return
     */
    private WorkflowProcess getWorkflowProcessByProcessId(String processId) {
        WorkflowDefinition wfd;
        try {
            wfd = runtimeContext.getPersistenceService().findTheLatestVersionOfWorkflowDefinitionByProcessId( processId);
        } catch (Exception e) {
            wfd = null;
        }
        return wfd == null ? null : wfd.getWorkflowProcess();
    }

    /***
     * 序列化流程定义文件
     * @param workflowProcess
     * @return
     */
    private String serializerWorkflowProcess(WorkflowProcess workflowProcess) {
        String wfpStr = null;
        try {
            wfpStr = new Dom4JFPDLSerializer().workflowProcessToXMLString(workflowProcess);
        } catch (IOException e) {
        } catch (FPDLSerializerException e) {
        }
        return wfpStr;
    }

    /***
     * 保存流程定义副本
     * @param workflowProcess
     */
    private void saveWorkflowProcessCopy(WorkflowProcess workflowProcess) {
        this.deleteWorkflowDefinitionCopy(workflowProcess.getId());//删除流程定义副本
        final WorkflowDefinition def = new WorkflowDefinition();
        def.setWorkflowProcess(workflowProcess);
        def.setState(true);
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                runtimeContext.getPersistenceService().saveOrUpdateWorkflowDefinition(def);
            }
        });
    }

    /***
     * 删除流程定义副本
     * @param processId
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteWorkflowDefinitionCopy(String processId) {
        workflowDefDao.removeByHSQL("from WorkflowDefinition o where o.processId=?", processId);
    }
    /***
     * 生成流程环节节点
     * @param params
     * @return
     */
    public JSONObject generateNode(Map<String,Object> params){
        String processId=params.get("processId")!=null?params.get("processId").toString():"";//流程id
        int nodeType=params.get("nodeType")!=null?Integer.parseInt(params.get("nodeType").toString()):0;//节点类型
        String x=params.get("x")!=null?params.get("x").toString():"";//x坐标
        String y=params.get("y")!=null?params.get("y").toString():"";//y坐标
        String fromNodeName=params.get("fromNodeName")!=null?params.get("fromNodeName").toString():"";//起始节点
        String toNodeName=params.get("toNodeName")!=null?params.get("toNodeName").toString():"";//结束节点

        StringBuffer errorMsg=new StringBuffer();
        WorkflowProcess wfp=this.getWorkflowProcessFromSession(processId);
        IWFElement currentNode=null;
        boolean setLocation=false;
        switch (nodeType){
            case FlowDefConstants.ELEMENT_TYPE_STARTNODE:{
                currentNode=this.generateStartNode(wfp,errorMsg);
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_FORMTASK:{
                currentNode=this.generateFormTaskNode(wfp,params,errorMsg);
                setLocation=true;
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_TOOLTASK:{
                currentNode=this.generateToolTaskNode(wfp,params,errorMsg);
                setLocation=true;
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_SYNCHRONIZER:{
                currentNode=this.generateSynchronizerNode(wfp,errorMsg);
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_ENDNODE:{
                currentNode=this.generateEndNode(wfp,errorMsg);
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_TRANSITION:{
                currentNode=this.generateTransitionNode(wfp,fromNodeName,toNodeName,errorMsg);
                break;
            }
        }
        if(errorMsg!=null&&errorMsg.length()>0){
            JSONObject jsonObject=new JSONObject();
            jsonObject.put("errorMsg",errorMsg);
            return jsonObject;
        }
        /***
         * 设置节点位置属性
         */
        if(!setLocation){
            Map<String, String> map = new HashMap<String, String>();
            map.put(ExtendedAttributeNames.BOUNDS_X,x);
            map.put(ExtendedAttributeNames.BOUNDS_Y,y);
            currentNode.getExtendedAttributes().putAll(map);
        }
        return this.returnNodeData(wfp,currentNode,nodeType);
    }

    /***
     * 生成节点返回数据
     * @param workflowProcess
     * @param element
     * @return
     */
    private JSONObject returnNodeData(WorkflowProcess workflowProcess,IWFElement element,int nodeType){
        JSONObject jsonObject=new JSONObject();
        jsonObject.put("id",element.getId());
        jsonObject.put("name",element.getName());
        jsonObject.put("displayName",element.getDisplayName());
        jsonObject.put("extendedAttributes",element.getExtendedAttributes());

        jsonObject.put("nodeType",nodeType);//节点类型

        if(element instanceof Task){
            Node node=(Node) getElementByName(workflowProcess, element.getName());
            jsonObject.put("x",node.getExtendedAttributes().get(ExtendedAttributeNames.BOUNDS_X));
            jsonObject.put("y",node.getExtendedAttributes().get(ExtendedAttributeNames.BOUNDS_Y));
            if(element instanceof FormTask){
                FormTask formTask=((FormTask)(((Activity)node).getTasks().get(0)));
                jsonObject.put("editForm",formTask.getEditForm()!=null?formTask.getEditForm().getUri():"");
                jsonObject.put("viewForm",formTask.getViewForm()!=null?formTask.getViewForm().getUri():"");
            }
        }else{
            jsonObject.put("x",element.getExtendedAttributes().get(ExtendedAttributeNames.BOUNDS_X));
            jsonObject.put("y",element.getExtendedAttributes().get(ExtendedAttributeNames.BOUNDS_Y));
        }


        jsonObject.put("defCode",serializerWorkflowProcess(workflowProcess));
        //workflowProcess.setName(workflowProcess.getName()+FlowDefConstants.FLOWCOPY_SUFFIX);
       // this.saveWorkflowProcessCopy(workflowProcess);
        return jsonObject;
    }

    /***
     * 拖拽移动环节节点
     * @param params
     * @return
     */
    public JSONObject dragNode(Map<String,Object> params){
        String processId=params.get("processId")!=null?params.get("processId").toString():"";//流程id
        String x=params.get("x")!=null?params.get("x").toString():"";//x坐标
        String y=params.get("y")!=null?params.get("y").toString():"";//y坐标
        String nodeName=params.get("nodeName")!=null?params.get("nodeName").toString():"";//节点名称

        StringBuffer errorMsg=new StringBuffer();
        WorkflowProcess wfp=this.getWorkflowProcessFromSession(processId);
        Node toNode = (Node) getElementByName(wfp, nodeName);
        if(toNode!=null){
            toNode.getExtendedAttributes().put(ExtendedAttributeNames.BOUNDS_X,x);
            toNode.getExtendedAttributes().put(ExtendedAttributeNames.BOUNDS_Y,y);
        }else{
            errorMsg.append("未找到拖拽的节点!");
        }

        if(errorMsg!=null&&errorMsg.length()>0){
            JSONObject jsonObject=new JSONObject();
            jsonObject.put("errorMsg",errorMsg);
            return jsonObject;
        }

        return this.returnNodeData(wfp,toNode,0);
    }
    /***
     * 修改节点名称
     * @param processId 流程id
     * @param nodeType 节点类型
     * @param nodeName 节点名称
     * @param displayName 节点显示名称
     * @return
     */
    public JSONObject updateNodeName(String processId,int nodeType,String nodeName,String displayName){
        StringBuffer errorMsg=new StringBuffer();
        WorkflowProcess wfp=this.getWorkflowProcessFromSession(processId);//从session中获取流程定义
        IWFElement currentNode=null;
        boolean setLocation=false;
        switch (nodeType){
            case FlowDefConstants.ELEMENT_TYPE_STARTNODE:{
                currentNode=wfp.getStartNode();
                currentNode.setDisplayName(displayName);
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_FORMTASK:{
                IWFElement ele=this.getElementByName(wfp,nodeName);
                if(ele instanceof Activity){
                    //设置activity名称
                    Activity acti=(Activity) ele;
                    acti.setDisplayName(displayName);
                    //设置task名称
                    currentNode=acti.getTasks().get(0);
                    currentNode.setDisplayName(displayName);
                }
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_TOOLTASK:{
                IWFElement ele=this.getElementByName(wfp,nodeName);
                if(ele instanceof Activity){
                    //设置activity名称
                    Activity acti=(Activity) ele;
                    acti.setDisplayName(displayName);
                    //设置task名称
                    currentNode=acti.getTasks().get(0);
                    currentNode.setDisplayName(displayName);
                }
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_SYNCHRONIZER:{
                IWFElement ele=this.getElementByName(wfp,nodeName);
                if(ele instanceof Synchronizer){
                    //设置activity名称
                    currentNode=(Synchronizer) ele;
                    currentNode.setDisplayName(displayName);

                }
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_ENDNODE:{
                currentNode=wfp.getEndNodes().get(0);
                currentNode.setDisplayName(displayName);
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_TRANSITION:{
                break;
            }
            default:{
                wfp.setDisplayName(displayName);
                JSONObject jsonObject=new JSONObject();
                jsonObject.put("defCode",serializerWorkflowProcess(wfp));
                //wfp.setName(wfp.getName()+FlowDefConstants.FLOWCOPY_SUFFIX);
                //this.saveWorkflowProcessCopy(wfp);
                return jsonObject;
            }
        }
        return this.returnNodeData(wfp,currentNode,nodeType);
    }
    /***
     * 修改节点属性
     * @param processId 流程id
     * @param nodeType 节点类型
     * @return
     */
    public JSONObject updateNodeAttribute(String processId,int nodeType,String nodeName,String attributeName,String attributeValue){
        StringBuffer errorMsg=new StringBuffer();
        WorkflowProcess wfp=this.getWorkflowProcessFromSession(processId);//从session中获取流程定义;
        IWFElement currentNode=null;
        switch (nodeType){
            case FlowDefConstants.ELEMENT_TYPE_FORMTASK:{
                IWFElement ele=this.getElementByName(wfp,nodeName);
                if(ele instanceof Activity){
                    //设置activity名称
                    Activity acti=(Activity) ele;
                    currentNode=acti.getTasks().get(0);
                    this.setFormTaskAttribute((Task)currentNode,attributeName,attributeValue);
                }
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_TOOLTASK:{
                IWFElement ele=this.getElementByName(wfp,nodeName);
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_TRANSITION:{
                break;
            }
        }
        return this.returnNodeData(wfp,currentNode,nodeType);
    }

    /***
     * 设置任务环节属性
     * @param
     * @param attributeName
     * @param attributeValue
     */
    private void setFormTaskAttribute(Task task,String attributeName,String attributeValue){
        if(task!=null&&task instanceof FormTask){
            FormTask formTask=(FormTask)task;
            if ("editForm".equals(attributeName)){//编辑表单
                Form editForm=formTask.getEditForm();
                if (editForm==null){
                    editForm=new Form("editForm");
                    formTask.setEditForm(editForm);
                }
                editForm.setUri(attributeValue);
            }else if ("viewForm".equals(attributeName)){//只读表单
                Form viewForm=formTask.getViewForm();
                if (viewForm==null){
                    viewForm=new Form("viewForm");
                    formTask.setViewForm(viewForm);
                }
                viewForm.setUri(attributeValue);
            }
        }
    }
    /***
     * 删除节点
     * @param processId 流程id
     * @param nodeType 节点类型
     * @param nodeName 节点名称
     * @return
     */
    public JSONObject deleteNode(String processId,int nodeType,String nodeName){
        StringBuffer errorMsg=new StringBuffer();
        WorkflowProcess wfp=this.getWorkflowProcessFromSession(processId);//从session中获取流程定义(processId);
        IWFElement currentNode=null;
        boolean setLocation=false;
        switch (nodeType){
            case FlowDefConstants.ELEMENT_TYPE_STARTNODE:{
                StartNode startNode=wfp.getStartNode();
                startNode.getLeavingTransitions().clear();

                List<Transition> tl=startNode.getLeavingTransitions();
                if (tl!=null){
                    for (int i=0;i<tl.size();i++){
                        wfp.getTransitions().remove(tl.get(i));
                    }
                }
                wfp.setStartNode(null);
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_FORMTASK:{
                IWFElement ele=this.getElementByName(wfp,nodeName);
                if(ele instanceof Activity){

                    Activity acti=(Activity) ele;
                    /*Transition tr=acti.getEnteringTransition();
                    if (tr!=null){
                        wfp.getTransitions().remove(tr);
                    }
                    Transition tl=acti.getLeavingTransition();
                    if (tl!=null){
                        wfp.getTransitions().remove(tl);
                    }*/

                    wfp.getTransitions().remove(acti.getLeavingTransition());
                    wfp.getTransitions().remove(acti.getEnteringTransition());
                    wfp.getActivities().remove(acti);
                }
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_TOOLTASK:{
                IWFElement ele=this.getElementByName(wfp,nodeName);
                if(ele instanceof Activity){
                    Activity acti=(Activity) ele;
                    wfp.getTransitions().remove(acti.getLeavingTransition());
                    wfp.getTransitions().remove(acti.getEnteringTransition());
                    wfp.getActivities().remove(acti);
                }
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_SYNCHRONIZER:{
                IWFElement ele=this.getElementByName(wfp,nodeName);
                Synchronizer syc=(Synchronizer) ele;
                List<Transition> tr=syc.getEnteringTransitions();
                if (tr!=null){
                    for (int i=0;i<tr.size();i++){
                        wfp.getTransitions().remove(tr.get(i));
                    }
                }
                List<Transition> tl=syc.getLeavingTransitions();
                if (tl!=null){
                    for (int i=0;i<tl.size();i++){
                        wfp.getTransitions().remove(tl.get(i));
                    }
                }
                //wfp.getTransitions().remove(syc.getEnteringTransitions());
               // wfp.getTransitions().remove(syc.getLeavingTransitions());
                wfp.getSynchronizers().remove(syc);
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_ENDNODE:{
                EndNode endNode=wfp.getEndNodes().get(0);
                List<Transition> tr=endNode.getEnteringTransitions();
                if (tr!=null){
                    for (int i=0;i<tr.size();i++){
                        wfp.getTransitions().remove(tr.get(i));
                    }
                }
                wfp.getEndNodes().remove(wfp.getEndNodes().get(0));
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_TRANSITION:{
                break;
            }
        }

        JSONObject jsonObject=new JSONObject();
        jsonObject.put("defCode",serializerWorkflowProcess(wfp));
        //wfp.setName(wfp.getName()+FlowDefConstants.FLOWCOPY_SUFFIX);
        //this.saveWorkflowProcessCopy(wfp);
        return jsonObject;
    }
    /***
     * 保存流程定义
     * @param processId 流程id
     * @return
     */
    public JSONObject saveFlowDef(String processId){
        StringBuffer errorMsg=new StringBuffer();
        //获取流程副本信息
        WorkflowProcess wfp = this.getWorkflowProcessFromSession(processId);
        if(wfp==null){
            errorMsg.append("找不到流程信息!");
        }else{
            //this.deleteWorkflowDefinitionCopy(processId+ FlowDefConstants.FLOWCOPY_SUFFIX);//删除流程定义副本
            WorkFlowSession.deleteWorkflowDefinition(processId);//删除session中流程定义
            wfp.setName(processId);
            final WorkflowDefinition def = new WorkflowDefinition();
            def.setWorkflowProcess(wfp);
            def.setPublishTime(new Date());
            def.setPublishUser(WorkFlowSession.getCurrentUser().getId());
            def.setState(true);
            transactionTemplate.execute(new TransactionCallbackWithoutResult() {
                protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                    runtimeContext.getPersistenceService().saveOrUpdateWorkflowDefinition(def);
                }
            });
        }
        JSONObject jsonObject=new JSONObject();
        if(errorMsg!=null&&errorMsg.length()>0){

            jsonObject.put("errorMsg",errorMsg);

        }
        return jsonObject;
    }
    /***
     * 根据流程id查询流程定义信息
     * @param processId
     * @return
     */
    public JSONObject queryFlowDefInfo(String processId){
        WorkflowProcess wfp=this.getWorkflowProcessCopy(processId);
        JSONObject jsonObject=new JSONObject();
        JSONArray nodeArray=new JSONArray();
        JSONArray lineArray=new JSONArray();

        jsonObject.put("id",wfp.getName());
        jsonObject.put("name",wfp.getName());
        jsonObject.put("displayName",wfp.getDisplayName());
        jsonObject.put("defCode",serializerWorkflowProcess(wfp));
        //查询流程关联的业务标识
        List<FlowBusiness> businessList=this.flowBusinessService.queryFlowBusinessIdentityByProcessId(processId);
        if (businessList!=null&&businessList.size()>0){
            jsonObject.put("businessIdentity",businessList.get(0).getIdentity());
        }
        //开始节点
        StartNode startNode=wfp.getStartNode();
        if(startNode!=null){
            JSONObject start=new JSONObject();
            start.put("id",startNode.getId());
            start.put("name",startNode.getName());
            start.put("displayName",startNode.getDisplayName());
            start.put("extendedAttributes",startNode.getExtendedAttributes());
            start.put("nodeType",FlowDefConstants.ELEMENT_TYPE_STARTNODE);
            start.put("x",startNode.getExtendedAttributes().get(ExtendedAttributeNames.BOUNDS_X));
            start.put("y",startNode.getExtendedAttributes().get(ExtendedAttributeNames.BOUNDS_Y));
            nodeArray.add(start);
        }

        //结束节点
        List<EndNode> endNodes=wfp.getEndNodes();
        if(endNodes!=null){
            for (int i=0;i<endNodes.size();i++){
                EndNode endNode=endNodes.get(i);
                JSONObject end=new JSONObject();
                end.put("id",endNode.getId());
                end.put("name",endNode.getName());
                end.put("displayName",endNode.getDisplayName());
                end.put("extendedAttributes",endNode.getExtendedAttributes());
                end.put("nodeType",FlowDefConstants.ELEMENT_TYPE_ENDNODE);
                end.put("x",endNode.getExtendedAttributes().get(ExtendedAttributeNames.BOUNDS_X));
                end.put("y",endNode.getExtendedAttributes().get(ExtendedAttributeNames.BOUNDS_Y));
                nodeArray.add(end);
            }
        }

        //环节
        List<Activity> actis=wfp.getActivities();
        if (actis!=null){
            for(int i=0;i<actis.size();i++){
                Activity a=actis.get(i);
                JSONObject task=new JSONObject();
                task.put("id",a.getTasks().get(0).getId());
                task.put("name",a.getTasks().get(0).getName());
                task.put("displayName",a.getTasks().get(0).getDisplayName());
                task.put("extendedAttributes",a.getTasks().get(0).getExtendedAttributes());
                if(a.getTasks().get(0) instanceof FormTask){
                    FormTask fTask=(FormTask)(a.getTasks().get(0));
                    task.put("nodeType",FlowDefConstants.ELEMENT_TYPE_FORMTASK);
                    task.put("editForm",fTask.getEditForm()!=null?fTask.getEditForm().getUri():"");
                    task.put("viewForm",fTask.getViewForm()!=null?fTask.getViewForm().getUri():"");
                }else{
                    task.put("nodeType",FlowDefConstants.ELEMENT_TYPE_TOOLTASK);
                }
                task.put("x",a.getExtendedAttributes().get(ExtendedAttributeNames.BOUNDS_X));
                task.put("y",a.getExtendedAttributes().get(ExtendedAttributeNames.BOUNDS_Y));
                nodeArray.add(task);
            }
        }

        //同步器
        List<Synchronizer> sycros=wfp.getSynchronizers();
        if (sycros!=null){
            for(int i=0;i<sycros.size();i++){
                Synchronizer a=sycros.get(i);
                JSONObject syn=new JSONObject();
                syn.put("id",a.getId());
                syn.put("name",a.getName());
                syn.put("displayName",a.getDisplayName());
                syn.put("extendedAttributes",a.getExtendedAttributes());
                syn.put("nodeType",FlowDefConstants.ELEMENT_TYPE_SYNCHRONIZER);
                syn.put("x",a.getExtendedAttributes().get(ExtendedAttributeNames.BOUNDS_X));
                syn.put("y",a.getExtendedAttributes().get(ExtendedAttributeNames.BOUNDS_Y));
                nodeArray.add(syn);
            }
        }

        //连接线
        List<Transition> trans=wfp.getTransitions();
        if (trans!=null){
            for(int i=0;i<trans.size();i++){
                Transition a=trans.get(i);
                JSONObject tra=new JSONObject();
                tra.put("id",a.getId());
                tra.put("name",a.getName());
                tra.put("displayName",a.getDisplayName());
                tra.put("extendedAttributes",a.getExtendedAttributes());
                tra.put("nodeType",FlowDefConstants.ELEMENT_TYPE_TRANSITION);
                String fromNodeName="";
                if(a.getFromNode() instanceof StartNode||a.getFromNode() instanceof EndNode||a.getFromNode() instanceof Synchronizer){
                    fromNodeName=a.getFromNode().getName();
                }else if(a.getFromNode() instanceof Activity){
                    fromNodeName=((Activity)a.getFromNode()).getTasks().get(0).getName();
                }
                tra.put("fromNodeName",fromNodeName);
                String toNodeName="";
                if(a.getToNode() instanceof StartNode||a.getToNode() instanceof EndNode||a.getToNode() instanceof Synchronizer){
                    toNodeName=a.getToNode().getName();
                }else if(a.getToNode() instanceof Activity){
                    toNodeName=((Activity)a.getToNode()).getTasks().get(0).getName();
                }
                tra.put("toNodeName",toNodeName);
                lineArray.add(tra);
            }
        }

        jsonObject.put("nodes",nodeArray);
        jsonObject.put("lines",lineArray);

        return jsonObject;
    }



    /***
     * 新建或修改流程定义信息
     * @param workflowDefObject
     * @return
     */
    public boolean createOrUpdateWorkflowDef(JSONObject workflowDefObject,User user){
        String processId=workflowDefObject.getString("processId");//流程id
        /*if(!(processId!=null&&!"".equals(processId.trim()))){//流程processId
            processId="WorkFlow"+DateTimeUtil.formatterDateTime("yyyyMMddHHmmss");
        }*/
        final WorkflowDefinition def = new WorkflowDefinition();
        def.setPublishTime(new Date());
        def.setPublishUser(user.getId());
        //创建WorkflowProcess
        WorkflowProcess wfp=new WorkflowProcess(processId);
        wfp.setDisplayName(workflowDefObject.getString("workflowName"));//流程显示名

        StringBuffer errorMsg=new StringBuffer();
        JSONArray activitys=workflowDefObject.getJSONArray("activitys");
        IWFElement preNode=null;
        for (int i=0;i<activitys.size();i++){
            JSONObject activity=(JSONObject)activitys.get(i);
            IWFElement currentNode=null;
            switch (activity.getInteger("activityType")){
                case FlowDefConstants.ELEMENT_TYPE_STARTNODE:{
                    //currentNode=this.generateStartNode(wfp,processId,activity.getString("activityName"),errorMsg);
                    break;
                }
                case FlowDefConstants.ELEMENT_TYPE_ACTIVITY:{
                    currentNode=this.generateActivityNode(wfp,processId,activity.getString("activityName"),activity,errorMsg);
                    break;
                }
                case FlowDefConstants.ELEMENT_TYPE_ENDNODE:{
                    currentNode=this.generateEndNode(wfp,errorMsg);
                    break;
                }
            }
            if(preNode!=null){
                this.joinElement(wfp,processId,preNode.getName(),currentNode.getName(),errorMsg);
            }
            preNode=currentNode;
        }
        def.setWorkflowProcess(wfp);
        def.setState(true);
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {

            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                runtimeContext.getPersistenceService().saveOrUpdateWorkflowDefinition(def);
            }
        });
        return true;
    }

    /***
     * 根据processId查询流程定义信息
     * @param processId
     * @return
     */
    public JSONObject queryWorkflowDefByProcessId(String processId){
        //查询流程定义信息
        WorkflowDefinition workflowDefinition=this.persistenceService.findTheLatestVersionOfWorkflowDefinitionByProcessId(processId);
        JSONObject workflowDef=new JSONObject();
        workflowDef.put("processId",workflowDefinition.getProcessId());
        workflowDef.put("workflowName",workflowDefinition.getDisplayName());
        WorkflowProcess workflowProcess=workflowDefinition.getWorkflowProcess();
        JSONArray activitys=new JSONArray();

        //开始节点
        JSONObject startObject=new JSONObject();
        IWFElement wfElement=workflowProcess.getStartNode();
        startObject.put("activityId",wfElement.getName());
        startObject.put("activityName",wfElement.getDisplayName());
        startObject.put("activityType",FlowDefConstants.ELEMENT_TYPE_STARTNODE);
        activitys.add(startObject);

        //任务节点
        List<Activity> activityList=workflowProcess.getActivities();
        for (Activity activity:activityList){
            JSONObject activityObject=new JSONObject();
            activityObject.put("activityId",activity.getName());
            activityObject.put("activityName",activity.getDisplayName());
            activityObject.put("activityType",FlowDefConstants.ELEMENT_TYPE_ACTIVITY);
            //编辑表单
            Form editForm=((FormTask)activity.getTasks().get(0)).getEditForm();
            activityObject.put("editForm",editForm!=null?editForm.getUri():"");
            //只读表单
            Form viewForm=((FormTask)activity.getTasks().get(0)).getViewForm();
            activityObject.put("viewForm",viewForm!=null?viewForm.getUri():"");
            //是否动态指定
            Map<String,String> extendedAttributes=((FormTask)activity.getTasks().get(0)).getExtendedAttributes();
            String isDynamicAssigner="0";
            if (extendedAttributes!=null&&extendedAttributes.get("isDynamicAssigner")!=null){
                isDynamicAssigner=extendedAttributes.get("isDynamicAssigner");
            }
            activityObject.put("isDynamicAssigner",isDynamicAssigner);

            activitys.add(activityObject);
        }

        //开始节点
        JSONObject endObject=new JSONObject();
        EndNode endElement=workflowProcess.getEndNodes().get(0);
        endObject.put("activityId",endElement.getName());
        endObject.put("activityName",endElement.getDisplayName());
        endObject.put("activityType",FlowDefConstants.ELEMENT_TYPE_ENDNODE);
        activitys.add(endObject);

        workflowDef.put("activitys",activitys);
        return workflowDef;
    }

    /***
     * 生成开始节点
     * @param workflowProcess 工作流对象
     * @param errorMsg 错误信息
     */
    private StartNode generateStartNode(WorkflowProcess workflowProcess,StringBuffer errorMsg) {
        if (workflowProcess == null) {
            errorMsg.append("workflowProcess" + FlowDefConstants.ERROR_OBJECT_NOTNULL);
            return null;
        }
        StartNode startNode = null;

        if (workflowProcess.getStartNode() == null) {
            //获取开始节点名称
            String name = this.getInitNameByType(workflowProcess, FlowDefConstants.ELEMENT_TYPE_STARTNODE);

            startNode = new StartNode(workflowProcess);
            //设置开始节点基本属性
            this.setElementBasicInfo(startNode,name,name, name,errorMsg);
            workflowProcess.setStartNode(startNode);
        } else {
            errorMsg.append("工作流已经存在开始节点！");
        }
        return startNode;
    }
    /***
     * 生成Activity节点
     * @param workflowProcess 工作流对象
     * @param errorMsg 错误信息
     */
    private Activity generateActivityNode(WorkflowProcess workflowProcess,String processId,String displayName,JSONObject activityData,StringBuffer errorMsg) {
        if (workflowProcess == null) {
            errorMsg.append("workflowProcess" + FlowDefConstants.ERROR_OBJECT_NOTNULL);
            return null;
        }
        //获取节点名称
        String name = this.getInitNameByType(workflowProcess, FlowDefConstants.ELEMENT_TYPE_ACTIVITY);
        /***
         * 设置节点位置属性
         */
        Map<String, String> map = new HashMap<String, String>();
        map.put(ExtendedAttributeNames.BOUNDS_X,Integer.toString(FlowDefConstants.INCREASE_X));
        map.put(ExtendedAttributeNames.BOUNDS_Y,Integer.toString(FlowDefConstants.INCREASE_Y));
        map.put(ExtendedAttributeNames.BOUNDS_HEIGHT,Integer.toString(FlowDefConstants.HEIGHT_NO_ACITVITY));
        map.put(ExtendedAttributeNames.BOUNDS_WIDTH,Integer.toString(FlowDefConstants.WIDTH_NO_ACITVITY));

        Activity activity = new Activity(workflowProcess,name);

        //设置开始节点基本属性
        this.setElementBasicInfo(activity, name,displayName, displayName,errorMsg);
        activity.getExtendedAttributes().putAll(map);


        //创建formTas任务
        FormTask formTask=new FormTask(activity,activity.getName()+".Task");
        formTask.setLoopStrategy(Task.NONE);//设置循环策略
        Participant performer=new Participant(formTask.getName()+".Performer");
        performer.setAssignmentHandler("com.weitu.workflow.definition.handler.DefaultUserAssignmentHandler");
        formTask.setPerformer(performer);

        //创建EventListener
        EventListener eventListener=new EventListener();
        eventListener.setClassName("com.weitu.workflow.definition.eventListener.FormTaskEventListener");
        formTask.getEventListeners().add(eventListener);

        //创建task表单
        if (activityData!=null&&activityData.get("editForm")!=null){
            Form editForm=new Form("editForm");
            editForm.setUri(activityData.getString("editForm"));
            formTask.setEditForm(editForm);
        }
        if (activityData!=null&&activityData.get("viewForm")!=null){
            Form viewForm=new Form("viewForm");
            viewForm.setUri(activityData.getString("viewForm"));
            formTask.setViewForm(viewForm);
        }
        if (activityData!=null&&activityData.get("isDynamicAssigner")!=null){//是否动态指定
            formTask.getExtendedAttributes().put("isDynamicAssigner",activityData.get("isDynamicAssigner").toString());
        }else{
            formTask.getExtendedAttributes().put("isDynamicAssigner","0");
        }
        activity.getInlineTasks().add(formTask);


        workflowProcess.getActivities().add(activity);
        return activity;
    }
    /***
     * 生成FormTask节点
     * @param workflowProcess 工作流对象
     * @param errorMsg 错误信息
     */
    private FormTask generateFormTaskNode(WorkflowProcess workflowProcess,Map<String,Object> paramsMap,StringBuffer errorMsg) {
        if (workflowProcess == null) {
            errorMsg.append("workflowProcess" + FlowDefConstants.ERROR_OBJECT_NOTNULL);
            return null;
        }
        //获取节点名称
        String name = this.getInitNameByType(workflowProcess, FlowDefConstants.ELEMENT_TYPE_ACTIVITY);


        Activity activity = new Activity(workflowProcess,name);

        //设置开始节点基本属性
        this.setElementBasicInfo(activity, name,name, name,errorMsg);
        String x=paramsMap.get("x")!=null?paramsMap.get("x").toString():"";//x坐标
        String y=paramsMap.get("y")!=null?paramsMap.get("y").toString():"";//y坐标
        Map<String, String> map = new HashMap<String, String>();
        map.put(ExtendedAttributeNames.BOUNDS_X,x);
        map.put(ExtendedAttributeNames.BOUNDS_Y,y);
        activity.getExtendedAttributes().putAll(map);

        //创建formTas任务
        String formTaskName=activity.getName()+".FormTask";
        FormTask formTask=new FormTask(activity,formTaskName);
        this.setElementBasicInfo(formTask, formTaskName,formTaskName, formTaskName,errorMsg);
        formTask.setLoopStrategy(Task.NONE);//设置循环策略
        Participant performer=new Participant(formTask.getName()+".Performer");
        performer.setAssignmentHandler("com.weitu.workflow.definition.handler.DefaultUserAssignmentHandler");
        formTask.setPerformer(performer);

        //创建EventListener
        EventListener eventListener=new EventListener();
        eventListener.setClassName("com.weitu.workflow.definition.eventListener.FormTaskEventListener");
        formTask.getEventListeners().add(eventListener);

        //创建task表单
        /*if (activityData!=null&&activityData.get("editForm")!=null){
            Form editForm=new Form("editForm");
            editForm.setUri(activityData.getString("editForm"));
            formTask.setEditForm(editForm);
        }
        if (activityData!=null&&activityData.get("viewForm")!=null){
            Form viewForm=new Form("viewForm");
            viewForm.setUri(activityData.getString("viewForm"));
            formTask.setViewForm(viewForm);
        }
        if (activityData!=null&&activityData.get("isDynamicAssigner")!=null){//是否动态指定
            formTask.getExtendedAttributes().put("isDynamicAssigner",activityData.get("isDynamicAssigner").toString());
        }else{
            formTask.getExtendedAttributes().put("isDynamicAssigner","0");
        }*/
        activity.getInlineTasks().add(formTask);


        workflowProcess.getActivities().add(activity);

        return formTask;

    }
    /***
     * 生成ToolTask节点
     * @param workflowProcess 工作流对象
     * @param errorMsg 错误信息
     */
    private ToolTask generateToolTaskNode(WorkflowProcess workflowProcess,Map<String,Object> paramsMap,StringBuffer errorMsg) {
        if (workflowProcess == null) {
            errorMsg.append("workflowProcess" + FlowDefConstants.ERROR_OBJECT_NOTNULL);
            return null;
        }
        //获取节点名称
        String name = this.getInitNameByType(workflowProcess, FlowDefConstants.ELEMENT_TYPE_ACTIVITY);


        Activity activity = new Activity(workflowProcess,name);

        //设置开始节点基本属性
        this.setElementBasicInfo(activity, name,name, name,errorMsg);
        String x=paramsMap.get("x")!=null?paramsMap.get("x").toString():"";//x坐标
        String y=paramsMap.get("y")!=null?paramsMap.get("y").toString():"";//y坐标
        Map<String, String> map = new HashMap<String, String>();
        map.put(ExtendedAttributeNames.BOUNDS_X,x);
        map.put(ExtendedAttributeNames.BOUNDS_Y,y);
        activity.getExtendedAttributes().putAll(map);

        //创建ToolTas任务
        String toolTaskName=activity.getName()+".ToolTask";
        ToolTask toolTask = new ToolTask(activity,toolTaskName);
        this.setElementBasicInfo(toolTask, toolTaskName,toolTaskName, toolTaskName,errorMsg);


        Application application = new Application("defaultHandler");// 设置自动环节的默认处理
        application.setDescription("defaultHandler");
        application.setHandler("defaultHandler");
        application.setDisplayName("defaultHandler");
        toolTask.setApplication(application);



        //创建EventListener
        EventListener eventListener=new EventListener();
        eventListener.setClassName("com.weitu.workflow.definition.eventListener.ToolTaskEventListener");
        toolTask.getEventListeners().add(eventListener);

        //创建task表单
        /*if (activityData!=null&&activityData.get("editForm")!=null){
            Form editForm=new Form("editForm");
            editForm.setUri(activityData.getString("editForm"));
            formTask.setEditForm(editForm);
        }
        if (activityData!=null&&activityData.get("viewForm")!=null){
            Form viewForm=new Form("viewForm");
            viewForm.setUri(activityData.getString("viewForm"));
            formTask.setViewForm(viewForm);
        }
        if (activityData!=null&&activityData.get("isDynamicAssigner")!=null){//是否动态指定
            formTask.getExtendedAttributes().put("isDynamicAssigner",activityData.get("isDynamicAssigner").toString());
        }else{
            formTask.getExtendedAttributes().put("isDynamicAssigner","0");
        }*/
        activity.getInlineTasks().add(toolTask);


        workflowProcess.getActivities().add(activity);

        return toolTask;

    }
    /***
     * 生成Synchronizer节点
     * @param workflowProcess 工作流对象
     * @param errorMsg 错误信息
     */
    private Synchronizer generateSynchronizerNode(WorkflowProcess workflowProcess, StringBuffer errorMsg) {
        if (workflowProcess == null) {
            errorMsg.append("workflowProcess" + FlowDefConstants.ERROR_OBJECT_NOTNULL);
            return null;
        }
        //生成Synchronizer节点
        String name=this.getInitNameByType(workflowProcess,FlowDefConstants.ELEMENT_TYPE_SYNCHRONIZER);
        Synchronizer synchronizer = new Synchronizer(workflowProcess, name);
        this.setElementBasicInfo(synchronizer,name,name,name,errorMsg);
        workflowProcess.getSynchronizers().add(synchronizer);
        return synchronizer;
    }
    /***
     * 生成Transition节点
     * @param workflowProcess 工作流对象
     * @param errorMsg 错误信息
     */
    private Transition generateTransitionNode(WorkflowProcess workflowProcess,String fromNodeName,String toNodeName, StringBuffer errorMsg) {
        if (workflowProcess == null) {
            errorMsg.append("workflowProcess" + FlowDefConstants.ERROR_OBJECT_NOTNULL);
            return null;
        }
        Node fromNode = (Node) getElementByName(workflowProcess, fromNodeName);
        Node toNode = (Node) getElementByName(workflowProcess, toNodeName);
        //生成EndNode节点
        String name=this.getInitNameByType(workflowProcess,FlowDefConstants.ELEMENT_TYPE_TRANSITION);
        Transition transition = new Transition(workflowProcess, name);
        setElementBasicInfo(transition, name, name, name,errorMsg);
        transition.setFromNode(fromNode);
        transition.setToNode(toNode);
        workflowProcess.getTransitions().add(transition);

        return transition;

    }

    /***
     * 生成EndNode节点
     * @param workflowProcess 工作流对象
     * @param errorMsg 错误信息
     */
    private EndNode generateEndNode(WorkflowProcess workflowProcess, StringBuffer errorMsg) {
        if (workflowProcess == null) {
            errorMsg.append("workflowProcess" + FlowDefConstants.ERROR_OBJECT_NOTNULL);
            return null;
        }
        EndNode endNode =null;
        //生成EndNode节点
        if (workflowProcess.getEndNodes() == null||workflowProcess.getEndNodes().size()==0) {
            //获取名称
            String name=this.getInitNameByType(workflowProcess,FlowDefConstants.ELEMENT_TYPE_ENDNODE);
            endNode = new EndNode(workflowProcess, name);
            setElementBasicInfo(endNode, name, name, name, errorMsg);
            workflowProcess.getEndNodes().add(endNode);
        } else {
            errorMsg.append("工作流已经存在结束节点！");
        }

        return endNode;

    }

    /***
     * 连接两个节点
     * @param workflowProcess
     * @param processId
     * @param fromNodeName
     * @param toNodeName
     * @param errorMsg
     */
    private void joinElement(WorkflowProcess workflowProcess, String processId,String fromNodeName,String toNodeName,StringBuffer errorMsg){
        Synchronizer synchronizer=this.generateSynchronizerNode(workflowProcess,errorMsg);
        //this.generateTransitionNode(workflowProcess,processId,fromNodeName,synchronizer.getName(),errorMsg);
        //this.generateTransitionNode(workflowProcess,processId,synchronizer.getName(),toNodeName,errorMsg);
    }
    /***
     * 设置节点元素基本属性
     * @param element 节点元素对象
     * @param name  元素名称
     * @param displayName 元素显示名
     * @param description 元素描述
     * @param errorMsg 错误信息
     */
    private void setElementBasicInfo(AbstractWFElement element, String name,String displayName, String description, StringBuffer errorMsg) {
        if (name != null && !"".equals(name)) {
            element.setName(name);
        } else {
            errorMsg.append(FlowDefConstants.ERROR_CANNOT_NULL);
        }
        element.setDisplayName(displayName);
        element.setDescription(displayName);
    }

    /***
     * 根据节点类型，自动生成节点名称
     * @param workflowProcess 流程对象
     * @param elementType 节点类型
     * @return
     */
    private String getInitNameByType(WorkflowProcess workflowProcess,int elementType) {
        String name = null;
        switch (elementType) {
            case FlowDefConstants.ELEMENT_TYPE_STARTNODE: {
                name = FlowDefConstants.INIT_STARTNODE_NAME;
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_ACTIVITY: {
                int num = workflowProcess.getActivities().size() + 1;
                do {
                    if (this.checkElementNameCanUse(workflowProcess, elementType,FlowDefConstants.INIT_ACTIVITY_NAME + num)) {
                        name = FlowDefConstants.INIT_ACTIVITY_NAME + num;
                    } else {
                        num++;
                    }

                } while (name == null);
                name = FlowDefConstants.INIT_ACTIVITY_NAME + num;
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_FORMTASK: {
                int num = 1;
                name = FlowDefConstants.INIT_FORMTASK_NAME + num;
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_SYNCHRONIZER: {
                int num = workflowProcess.getSynchronizers().size() + 1;
                do {
                    if (checkElementNameCanUse(workflowProcess, elementType,FlowDefConstants.INIT_SYNCHRONIZER_NAME + num)) {
                        name = FlowDefConstants.INIT_SYNCHRONIZER_NAME + num;
                    } else {
                        num++;
                    }

                } while (name == null);
                name = FlowDefConstants.INIT_SYNCHRONIZER_NAME + num;
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_ENDNODE: {
                name = FlowDefConstants.INIT_ENDNODE_NAME;
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_TRANSITION: {
                int num = workflowProcess.getTransitions().size() + 1;
                do {
                    if (checkElementNameCanUse(workflowProcess, elementType,FlowDefConstants.INIT_TRANSITION_NAME + num)) {
                        name = FlowDefConstants.INIT_TRANSITION_NAME + num;
                    } else {
                        num++;
                    }

                } while (name == null);
                name = FlowDefConstants.INIT_TRANSITION_NAME + num;
                break;
            }
            /*
            case FlowDefConstants.ELEMENT_TYPE_ENDNODE: {
                int num = workflowProcess.getEndNodes().size() + 1;
                do {
                    if (nameIfCanUse(workflowProcess, elementType,
                            FlowDefConstants.INIT_ENDNODE_NAME + num)) {
                        name = FlowDefConstants.INIT_ENDNODE_NAME + num;
                    } else {
                        num++;
                    }

                } while (name == null);
                name = FlowDefConstants.INIT_ENDNODE_NAME + num;
                break;
            }





            case FlowDefConstants.ELEMENT_TYPE_TOOLTASK: {
                int num = getInlineTasksNum(workflowProcess);
                name = FlowDefConstants.INIT_TOOLTASK_NAME + num;
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_TRANSITION: {
                int num = workflowProcess.getTransitions().size() + 1;
                do {
                    if (nameIfCanUse(workflowProcess, elementType,
                            FlowDefConstants.INIT_TRANSITION_NAME + num)&&
                            nameIfCanUse(workflowProcess, elementType,
                                    FlowDefConstants.INIT_TRANSITION_NAME + num + FlowDefConstants.BRFLAG)) {
                        name = FlowDefConstants.INIT_TRANSITION_NAME + num;
                    } else {
                        num++;
                    }

                } while (name == null);
                name = FlowDefConstants.INIT_TRANSITION_NAME + num;
                break;
            }*/
        }
        return name;
    }

    /***
     * 验证节点名称是否可以使用
     * @param workflowProcess 流程对象
     * @param elementType 节点类型
     * @param name 节点名称
     * @return
     */
    private Boolean checkElementNameCanUse(WorkflowProcess workflowProcess,int elementType, String name) {
        Boolean isCanUse = true;
        switch (elementType) {
            case FlowDefConstants.ELEMENT_TYPE_ACTIVITY: {
                for (Activity activity : workflowProcess.getActivities()) {
                    if (activity.getName().equals(name)) {
                        isCanUse = false;
                        break;
                    }
                }
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_SYNCHRONIZER: {
                for (Synchronizer syn : workflowProcess.getSynchronizers()) {
                    if (syn.getName().equals(name)) {
                        isCanUse = false;
                        break;
                    }
                }
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_TRANSITION: {
                for (Transition tran : workflowProcess.getTransitions()) {
                    if (tran.getName().equals(name)) {
                        isCanUse = false;
                        break;
                    }
                }
                break;
            }
           /* case FlowDefConstants.ELEMENT_TYPE_ENDNODE: {
                for (EndNode end : workflowProcess.getEndNodes()) {
                    if (end.getName().equals(name)) {
                        isCanUse = false;
                        break;
                    }
                }
                break;
            }
            case FlowDefConstants.ELEMENT_TYPE_LOOP: {
                for (Loop loop : workflowProcess.getLoops()) {
                    if (loop.getName().equals(name)) {
                        isCanUse = false;
                        break;
                    }
                }
                break;
            }
            */
        }
        return isCanUse;
    }

    /***
     * 根据节点名称获取节点
     * @param workflowProcess
     * @param elementName
     * @return
     */
    private AbstractWFElement getElementByName(WorkflowProcess workflowProcess,String elementName) {
        if (workflowProcess != null) {
            if (workflowProcess.getStartNode()!=null&&workflowProcess.getStartNode().getName().equals(elementName)) {// StartNode只能作为fromNode
                return workflowProcess.getStartNode();
            }
            for (Activity act : workflowProcess.getActivities()) {
                if (act.getName().equals(elementName)) {
                    return act;
                }
                for (Task t : act.getTasks()) {
                    if (t.getName().equals(elementName)) {
                        return act;
                    }
                }
            }
            for (Synchronizer syn : workflowProcess.getSynchronizers()) {
                if (syn.getName().equals(elementName)) {
                    return syn;
                }
            }
            for (EndNode end : workflowProcess.getEndNodes()) { // EndNode只能作为toNode
                if (end.getName().equals(elementName)) {
                    return end;
                }
            }
            for (Transition tran : workflowProcess.getTransitions()) {
                if (tran.getName().equals(elementName)) {
                    return tran;
                }
            }
        }
        return null;
    }

    /***
     * 测试保存类
     */
    public void saveWorkflow(){
        final WorkflowDefinition def = new WorkflowDefinition();
        //创建WorkflowProcess
        String processId="WorkFlow"+DateTimeUtil.formatterDateTime("yyyyMMddHHmmss");
        WorkflowProcess wfp=new WorkflowProcess(processId);

        StringBuffer errorMsg=new StringBuffer();
        IWFElement node1=this.generateStartNode(wfp,errorMsg);
        IWFElement node2=this.generateActivityNode(wfp,processId,"",null,errorMsg);
        this.joinElement(wfp,processId,node1.getName(),node2.getName(),errorMsg);
        IWFElement node3=this.generateActivityNode(wfp,processId,"",null,errorMsg);
        this.joinElement(wfp,processId,node2.getName(),node3.getName(),errorMsg);
        IWFElement node4=this.generateEndNode(wfp,errorMsg);
        this.joinElement(wfp,processId,node3.getName(),node4.getName(),errorMsg);
        def.setWorkflowProcess(wfp);
        def.setState(true);
        /*transactionTemplate.execute(new TransactionCallbackWithoutResult() {

            protected void doInTransactionWithoutResult(
                    TransactionStatus transactionStatus) {*/
        runtimeContext.getPersistenceService()
                .saveOrUpdateWorkflowDefinition(def);
          /*  }
        });*/
    }


    public WorkflowDefDao getWorkflowDefDao() {
        return workflowDefDao;
    }

    public void setWorkflowDefDao(WorkflowDefDao workflowDefDao) {
        this.workflowDefDao = workflowDefDao;
    }

    public RuntimeContext getRuntimeContext() {
        return runtimeContext;
    }

    public void setRuntimeContext(RuntimeContext runtimeContext) {
        this.runtimeContext = runtimeContext;
    }

    public TransactionTemplate getTransactionTemplate() {
        return transactionTemplate;
    }

    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }

    public WorkflowDefMapper getWorkflowDefMapper() {
        return workflowDefMapper;
    }

    public void setWorkflowDefMapper(WorkflowDefMapper workflowDefMapper) {
        this.workflowDefMapper = workflowDefMapper;
    }

    public IPersistenceService getPersistenceService() {
        return persistenceService;
    }

    public void setPersistenceService(IPersistenceService persistenceService) {
        this.persistenceService = persistenceService;
    }

    public static Dom4JFPDLSerializer getSerializer() {
        return serializer;
    }

    public static void setSerializer(Dom4JFPDLSerializer serializer) {
        WorkflowDefServiceImpl.serializer = serializer;
    }

    public FlowBusinessService getFlowBusinessService() {
        return flowBusinessService;
    }

    public void setFlowBusinessService(FlowBusinessService flowBusinessService) {
        this.flowBusinessService = flowBusinessService;
    }
}
